// X-Chat TIGCC Doc search plugin by Raoul Prévost
// from xctigcc.c by Kevin Kofler
// Portions lifted from the X-Chat plugin examples by Peter Zelezný (GPLed) and
// from testfetch.c by Lyle Hanson (Public Domain).

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "xchat-plugin.h"
#define URL_BASE "http://tigcc.ticalc.org/doc/"

#include "xcdoc.h"

extern const Cle xcdoc_cles[];
extern const Cle xcdoc_case_cles[];
extern const size_t xcdoc_nb_cles;

int clecmp(const void *cle1, const void *cle2) {
	return strcmp(((Cle*)cle1)->mot, ((Cle*)cle2)->mot);
}

int clecasecmp(const void *cle1, const void *cle2) {
	return strcasecmp(((Cle*)cle1)->mot, ((Cle*)cle2)->mot);
}

int verbose_debug = 0;	// avoid linkage error

static xchat_plugin *ph;   /* plugin handle */

Cle *data_cherche(const char *nom) {
	Cle cle_key = ((Cle) {nom, 0, NULL});
	return (Cle*)(bsearch(&cle_key, xcdoc_cles, xcdoc_nb_cles, sizeof(Cle), clecmp));
}

Cle *data_cherche_casse(const char *nom) {
	Cle cle_key = ((Cle) {nom, 0, NULL});
	return (Cle*)(bsearch(&cle_key, xcdoc_case_cles, xcdoc_nb_cles, sizeof(Cle), clecasecmp));
}

static int timeout_cb(void *userdata) {
	const char *nick = (char*)(userdata + sizeof(xchat_context*));
	const char *sender = (char*)(nick + strlen(nick) + 1);
	const char *look_for = (char*)(sender + strlen(sender) + 1);
	xchat_set_context(ph, *(xchat_context**)userdata);
	size_t i;

	Cle *found = data_cherche(look_for);
	if (found || (found = data_cherche_casse(look_for))) {
		for (i = 0; i < found->nb_liens; i++) {
			xchat_commandf(ph, "msg %s %s %s%s", sender, found->liens[i].titre, URL_BASE, found->liens[i].url);
		}
	} else xchat_commandf(ph, "msg %s %s: \"%s\" not found.", sender, nick, look_for);

	
	free(userdata);
	return 0;
}

static int chanmsg_all_cb(char *word[], void *userdata, const char *sender) {
	if (!strncmp(word[2], "!doc ", 5)) {
		char *buffer = malloc(sizeof(xchat_context*) + strlen(sender) + strlen(word[2]) + strlen(word[1]) - 2);
		*(xchat_context**)buffer = xchat_get_context(ph);
		strcpy(buffer + sizeof(xchat_context*), word[1]);
		strcpy(buffer + sizeof(xchat_context*) + strlen(word[1]) + 1, sender);
		strcpy(buffer + sizeof(xchat_context*) + strlen(word[1]) + strlen(sender) + 2, word[2] + 5);
		xchat_hook_timer(ph, 1, timeout_cb, buffer);
	}
	return XCHAT_EAT_NONE;
}

static int chanmsg_private_cb(char *word[], void *userdata) {
	return chanmsg_all_cb(word, userdata, word[1]);
}

static int chanmsg_channel_cb(char *word[], void *userdata) {
	return chanmsg_all_cb(word, userdata, xchat_get_info(ph,"channel"));
}

__declspec(dllexport)
int xchat_plugin_init(xchat_plugin *plugin_handle,
                      char **plugin_name,
                      char **plugin_desc,
                      char **plugin_version,
                      char *arg) {
	/* we need to save this for use with any xchat_* functions */
	ph = plugin_handle;

	*plugin_name = "X-Chat TIGCC Doc";
	*plugin_desc = "Shows TIGCC doc on !doc function_name.";
	*plugin_version = "0.31";

	xchat_hook_print(ph, "Channel Message", XCHAT_PRI_NORM, chanmsg_channel_cb, NULL);
	xchat_hook_print(ph, "Your Message", XCHAT_PRI_NORM, chanmsg_channel_cb, NULL);
	xchat_hook_print(ph, "Private Message", XCHAT_PRI_NORM, chanmsg_private_cb, NULL);
	xchat_hook_print(ph, "Private Message to Dialog", XCHAT_PRI_NORM, chanmsg_private_cb, NULL);

	xchat_print(ph, "TIGCC Doc plugin loaded successfully!\n");

	return 1;       /* return 1 for success */
}

__declspec(dllexport)
int xchat_plugin_deinit(void) {

	xchat_print(ph, "TIGCC Doc plugin unloaded successfully!\n");

	return 1;       /* return 1 for success */
}
